package com.WPMS;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Location;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.widget.Toast;


public class WiFiPositioningSystem extends WPSPublisher 
{
	private final Context context;
	private final WifiManager wifiManager;
	
	private Map<String, List<WPMSScanResult> > wifiMap;
	
	private Location location;
	private List<ScanResult> scanResults;

	
	public WiFiPositioningSystem(Context context)
	{
		// Save off the instantiating activity for later use
		this.context = context;
		
		// Get the wifi manager for this context
		this.wifiManager = (WifiManager) this.context.getSystemService(Context.WIFI_SERVICE);
		
		// Initialize wifiMap
		this.wifiMap = new HashMap<String, List<WPMSScanResult> >();
	}
	
	
	
	private void calculatePosition()
	{
		// Iterate over current scan results creating a set of valid positions for each
		for (ScanResult scanResult: scanResults)
		{
			// Get Range of Signal Strengths grouped by position 
		}
	}
	

	
	public void startPositioning()
	{
		// Load Map of Wifi Strengths
		loadMap();
		
		// Register event listener for scan completion
		context.registerReceiver(broadcastReceiver, 
				new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
		
		// Begin scanning for wireless access points
		wifiManager.startScan();
	}

	
	public void stopPositioning()
	{
		// Stop listening for WAP Scan Updates
		context.unregisterReceiver(broadcastReceiver);
	}
	
	
	private void publish()
	{
		// Only publish if we've established a location
		if (null != location)
		{
			// Update current map data
		//	currentPositionData.setScanResults(scanResults);
			
			// Push data to subscribers
			// TODO: Refactor away from passed parameter
			//publish(currentPositionData);
		}
	}

	
	
	/**
	 * Loads a map of Wifi signal strengths into memory
	 */
	private void loadMap()
	{
		// TODO: Integrate this with the storage subsystem instead of dummy data
		wifiMap.clear();
		
		// Wap IDs @ Brian's Desk:
		// Position: 42.4350374, -73.2327103
		// 00:1b:63:2b:5f:a9 / -57, -58, -63, -57
		// 48:5b:39:c8:8d:02 / -77, -74, -74, -74
		// 00:1f:5b:86:e3:45 / -79, -81, -88, -82
		// 0c:d5:02:4f:c3:70 / -100, -100, -97, -100
		// 00:26:f2:7e:17:14 / -62, -63, -61, -62
		WPMSLocation testLocation = new WPMSLocation(42, -73);
		
		List<WPMSScanResult> wpmsScanResults = new ArrayList<WPMSScanResult>();
		
		String currentBSSID = "00:1b:63:2b:5f:a9";
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -57, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -58, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -63, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -57, testLocation));
		
		wifiMap.put(currentBSSID, wpmsScanResults);
		wpmsScanResults.clear();
		
		
		currentBSSID = "48:5b:39:c8:8d:02";
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -77, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -74, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -74, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -74, testLocation));
		
		wifiMap.put(currentBSSID, wpmsScanResults);
		wpmsScanResults.clear();
		
		
		currentBSSID = "00:1f:5b:86:e3:45";
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -79, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -81, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -88, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -82, testLocation));
		
		wifiMap.put(currentBSSID, wpmsScanResults);
		wpmsScanResults.clear();
		
		
		currentBSSID = "0c:d5:02:4f:c3:70";
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -100, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -100, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -97, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -100, testLocation));
		
		wifiMap.put(currentBSSID, wpmsScanResults);
		wpmsScanResults.clear();
		
		
		currentBSSID = "00:26:f2:7e:17:14";
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -62, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -63, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -61, testLocation));
		wpmsScanResults.add(new WPMSScanResult(currentBSSID, -62, testLocation));
		
		wifiMap.put(currentBSSID, wpmsScanResults);
		wpmsScanResults.clear();		
	}
	
	
	
	private BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
	{
		@Override
		public void onReceive(Context context, Intent intent) 
		{
	    	if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
	    	{	// WiFi Scan Results Received
				// Process event
				scanResults = wifiManager.getScanResults();
				
				// Determine position
				calculatePosition();
				
				// Update subscribers
				WiFiPositioningSystem.this.publish();
				
				// Request another scan
				wifiManager.startScan();
				WPSDebug(scanResults.toString());
	    	}
		}
	};

	
	private void WPSDebug(String someText)
	{
    	//TODO
    	Toast toast;
    	int duration = Toast.LENGTH_SHORT;
    	toast = Toast.makeText(context, someText, duration);
    	toast.show();
	}
	
	
}

